﻿using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Text;

namespace Dapr.Actors.Generators
{
    /// <summary>
    /// Templates for generating source code.
    /// </summary>
    internal static partial class Templates
    {
        /// <summary>
        /// Returns the <see cref="SourceText"/> for the ActorMethodAttribute.
        /// </summary>
        /// <param name="destinationNamespace">Namespace where to generate attribute.</param>
        /// <returns>The <see cref="SourceText"/> representing the ActorMethodAttribute.</returns>
        /// <exception cref="ArgumentNullException">Throws when destinationNamespace is null.</exception>
        public static SourceText ActorMethodAttributeSourceText(string destinationNamespace)
        {
            if (destinationNamespace is null)
            {
                throw new ArgumentNullException(nameof(destinationNamespace));
            }

            var source = $@"
// <auto-generated/>

#nullable enable

using System;

namespace {destinationNamespace}
{{
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
    internal sealed class {Constants.ActorMethodAttributeTypeName} : Attribute
    {{
        public string? Name {{ get; set; }}
    }}
}}";

            return SourceText.From(
                SyntaxFactory.ParseCompilationUnit(source)
                    .NormalizeWhitespace()
                    .ToFullString(),
                Encoding.UTF8);
        }

        /// <summary>
        /// Returns the <see cref="SourceText"/> for the GenerateActorClientAttribute.
        /// </summary>
        /// <param name="destinationNamespace">Namespace where to generate attribute.</param>
        /// <returns>The <see cref="SourceText"/> representing the ActorMethodAttribute.</returns>
        /// <exception cref="ArgumentNullException">Throws when destinationNamespace is null.</exception>
        public static SourceText GenerateActorClientAttributeSourceText(string destinationNamespace)
        {
            if (destinationNamespace is null)
            {
                throw new ArgumentNullException(nameof(destinationNamespace));
            }

            string source = $@"
// <auto-generated/>

#nullable enable

using System;

namespace {destinationNamespace}
{{
    [AttributeUsage(AttributeTargets.Interface, AllowMultiple = false, Inherited = false)]
    internal sealed class {Constants.GenerateActorClientAttributeTypeName} : Attribute
    {{
        public string? Name {{ get; set; }}

        public string? Namespace {{ get; set; }}
    }}
}}";

            return SourceText.From(
                SyntaxFactory.ParseCompilationUnit(source)
                    .NormalizeWhitespace()
                    .ToFullString(),
                Encoding.UTF8);
        }
    }
}
